package com.lanxin.xxform.tools;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class JetCriteria {
	
	//条件连接方式
    public final static String OPT_AND      = "AND";
    public final static String OPT_OR       = "OR";

    //排序方式
    public final static String ORDER_ASC    = "ASC";
    public final static String ORDER_DESC   = "DESC";

    //联合方式
    public final static String JOIN_INNER   = "inner";
    public final static String JOIN_LEFT    = "left";
    public final static String JOIN_RIGHT   = "right";

    //字段
    private String select = "*";
    //成员条件
    private LinkedHashMap<String, String[]> items = new LinkedHashMap<>();
    //自定义条件
	private String condition = "";
	//联合
    private String union = "";
	//排序
	private String order = "";
	//分组
	private String group = "";
	//分页
    private String page = "";
    
    /**
     * 设置查询字段
     * @param select
     */
    public void setSelect(String select) {
        if (select != null && !select.isEmpty()) {
            this.select = select;
        }
    }

    public String getSelect() {
        return select;
    }

    /**
     * 判断是否包含筛选字段
     * @param field
     * @return
     */
    public boolean existField(String field) {
        if (!field.isEmpty() && (items.containsKey(field) || condition.indexOf(field) > -1))
            return true;
        return false;
    }

    /**
     * 添加查询条件
     * @param field 字段
     * @param value 值
     */
    public void add(String field, String value) {
        if (value != null && !value.isEmpty()) {
            items.put(field, new String[]{"='" + addSlashes(value) +"'", OPT_AND});
        }
    }

    /**
     * 添加查询条件
     * @param field 字段
     * @param value 值
     */
    public void add(String field, int value) {
        items.put(field, new String[]{"=" + value, OPT_AND});
    }

    /**
     * 添加查询条件
     * @param field 字段
     * @param value 值
     */
    public void add(String field, long value) {
        items.put(field, new String[]{"=" + value, OPT_AND});
    }

    /**
     * 添加查询条件
     * @param field     字段
     * @param symbol    连接符号
     * @param value     值
     */
    public void add(String field, String symbol, String value) {
        if (value != null && !value.isEmpty()) {
            items.put(field, new String[]{" " + symbol + " '" + addSlashes(value) +"'", OPT_AND});
        }
    }

    /**
     * 添加查询条件
     * @param field     字段
     * @param symbol    连接符号
     * @param value     值
     */
    public void add(String field, String symbol, int value) {
        items.put(field, new String[]{" " + symbol + " " + value, OPT_AND});
    }

    /**
     * 添加查询条件
     * @param field     字段
     * @param symbol    连接符号
     * @param value     值
     */
    public void add(String field, String symbol, long value) {
        items.put(field, new String[]{" " + symbol + " " + value, OPT_AND});
    }

    /**
     * 添加查询条件
     * @param field     字段
     * @param symbol    连接符号
     * @param value     值
     */
    public void add(String field, String symbol, double value) {
        items.put(field, new String[]{" " + symbol + " " + value, OPT_AND});
    }

    /**
     * 添加查询条件(OR)
     * @param field 字段
     * @param value 值
     */
    public void addOR(String field, String value) {
        if (value != null && !value.isEmpty()) {
            items.put(field, new String[]{"='" + addSlashes(value) +"'", OPT_OR});
        }
    }

    /**
     * 添加查询条件(OR)
     * @param field 字段
     * @param value 值
     */
    public void addOR(String field, int value) {
        items.put(field, new String[]{"=" + value, OPT_OR});
    }

    /**
     * 添加查询条件(OR)
     * @param field     字段
     * @param value     值
     * @param symbol    连接符号
     */
    public void addOR(String field, String symbol, String value) {
        if (value != null && !value.isEmpty()) {
            items.put(field, new String[]{"=" + value, OPT_OR});
        }
    }

    /**
     * 添加查询条件（NOT）
     * @param field
     * @param value
     */
    public void addNot(String field, String value) {
        items.put(field, new String[]{"!='" + addSlashes(value) +"'", OPT_AND});
    }

    /**
     * 添加查询条件（NOT)
     * @param field
     * @param value
     */
    public void addNot(String field, int value) {
        items.put(field, new String[]{"!=" + value, OPT_AND});
    }

    /**
     * 添加查询条件（NOT)
     * @param field
     * @param value
     */
    public void addNot(String field, long value) {
        items.put(field, new String[]{"!=" + value, OPT_AND});
    }

    /**
     * select IN 查询条件
     * @param field
     * @param args
     */
    public void addIn(String field, String args[]) {
        if (args.length > 0) {
            items.put(field, new String[]{" IN ('" + String.join("','", args) + "')", OPT_AND});
        }
    }

    /**
     * select IN查询
     * @param field
     * @param args
     */
    public void addIn(String field, int args[]) {
        if (args.length > 0) {
            StringBuilder stringBuilder = new StringBuilder();
            for (int item : args) {
                stringBuilder.append("," + item);
            }
            items.put(field, new String[]{" IN (" + stringBuilder.toString().substring(1) + ")", OPT_AND});
        }
    }

    public void addIn(String field, List<String> args) {
        if (args.size() > 0) {
            StringBuilder stringBuilder = new StringBuilder();
            for (String item : args) {
                stringBuilder.append("','" + item);
            }
            items.put(field, new String[]{" IN ('" + stringBuilder.toString().substring(3) + "')", OPT_AND});
        }
    }

    /**
     * Like模糊查询
     * @param field
     * @param value
     */
    public void addLike(String field, String value) {
        if (value != null && !value.isEmpty()) {
            items.put(field, new String[]{" like '%" + addSlashes(value) +"%'", OPT_AND});
        }
    }

    /**
     * 删除成员条件
     * @param field
     * @return
     */
    public boolean remove(String field) {
        if (items.containsKey(field)) {
            items.remove(field);
            return true;
        }
        return false;
    }

    /**
     * 添加自定义查询条件
     * @param condition 条件
     * @param opt       操作符
     */
    public void addCondition(String condition, String opt) {
        if (this.condition.isEmpty()) {
            this.condition = condition;
        } else {
            this.condition = "(" + this.condition + ") " + opt + " " + condition;
        }
    }

    /**
	 * 过滤SQL注入字符
	 * @param str
	 * @return
	 */
	private String addSlashes(String str) {
        str = str.replace("\\", "\\\\");
		str = str.replace("\'", "\\'");
		str = str.replace("\"", "\\\"");
		return str;
	}

    /**
     * 联合查询
     * @param tableName 联合表名称
     * @param foreign   外键关系
     * @param type      联合方式 - inner | left | right
     */
    public void setUnion(String tableName, String foreign, String type) {
        if (this.union.isEmpty()) {
            this.union = type + " join " + tableName + " on " + foreign;
        } else {
            this.union += " " + type + " join " + tableName + " on " + foreign;
        }
    }

    /**
     * 按字段排序
     * @param field
     * @param type
     */
    public void orderBy(String field, String type) {
        if (this.order.isEmpty()) {
            this.order = field + " " + type;
        } else {
            this.order += "," + field + " " + type;
        }   
    }

    /**
     * 按字段分组
     * @param field
     */
    public void groupBy(String field) {
        this.group = field;
    }

    /**
     * 设置分页
     * @param offset
     * @param limit
     */
    public void setPage(int offset, int limit) {
        if (limit == 0) {
            limit = 1;
        }
        this.page = offset + "," + limit;
    }
    
    /**
     * 构建单表查询语句
     * @return
     */
    public String getCondition() {
        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String[]> entry : items.entrySet()) {
            String[] v = entry.getValue();
            if (stringBuilder.length() > 0) {
                stringBuilder.append(v[1] + " " + entry.getKey() + v[0] + " ");
            } else {
                stringBuilder.append(entry.getKey() + v[0] + " ");
            }
        }
        String c = "";
        if (! condition.isEmpty()) {
            c = " where (" + condition + ") ";
        }
        if (stringBuilder.length() > 0) {
            if (! c.isEmpty()) {
                return c + JetCriteria.OPT_AND + " " + stringBuilder.toString();
            } else {
                return " where " + stringBuilder.toString();
            }
        } else {
            return c;
        }
    }

    /**
     * 构建联表查询语句
     * @return
     */
    public String getJoinCondition() {
        return this.union + " " + getCondition();
    }

    /**
     * 构建查询条件
     * @return
     */
    public String getFullCondition() {
        StringBuilder stringBuilder = new StringBuilder();
        if (!this.union.isEmpty()) {
            stringBuilder.append(this.union);
        }
        stringBuilder.append(getCondition());
        if (!this.group.isEmpty()) {
            stringBuilder.append(" group by " + this.group);
        }
        if (!this.order.isEmpty()) {
            stringBuilder.append(" order by " + this.order);
        }
        if (!this.page.isEmpty()) {
            stringBuilder.append(" limit " + this.page);
        }
        return stringBuilder.toString();
    }
	
}